﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.Caching;
using System.Threading.Tasks;
using System.Web;

namespace MakeWeekConcerts.Models
{
    public class ArtistDetailResponse
    {
        private static MemoryCache ArtistCache = new MemoryCache("Artists");
        private static string LastFmArtistInfoUrl = "http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist={0}&api_key=03c448f21eeadd7ee6bcfd97acd49f4f&format=json";

        [JsonProperty("artist")]
        public ArtistDetail Artist { get; set; }

        public static async Task<ArtistDetailResponse> GetArtistDetail(string artistName)
        {
            if (ArtistCache.Contains(artistName))
            {
                return (ArtistDetailResponse)ArtistCache.Get(artistName);
            }

            var client = new HttpClient();
            var encodedName = HttpUtility.UrlEncode(artistName.Trim());
            var uri = string.Format(LastFmArtistInfoUrl, encodedName);
            Trace.TraceInformation("Loading artist info for {0} from {1}", artistName, uri);
            var response = await client.GetAsync(uri);
            if (response.StatusCode != System.Net.HttpStatusCode.OK)
                return null;

            var ser = JsonSerializer.Create();
            using (var reader = new JsonTextReader(new StreamReader(await response.Content.ReadAsStreamAsync())))
            {
                ArtistDetailResponse artistInfo = null;
                try
                {
                    artistInfo = ser.Deserialize<ArtistDetailResponse>(reader);
                }
                catch (JsonSerializationException e)
                {
                    Trace.TraceError("Failed to find any artist info for {0}: {1}", artistName, e.Message);
                    artistInfo = new ArtistDetailResponse() { Artist = new ArtistDetail() { Name = artistName } };
                }
                artistInfo.Artist.Videos = await YoutubeVideo.GetVideosFor(artistName);
                ArtistCache.Add(artistName, artistInfo, new CacheItemPolicy() { SlidingExpiration = TimeSpan.FromDays(1) });
                return artistInfo;
            }
        }
    }

    public class ArtistDetail
    {
        public ArtistDetail()
        {
            this.Images = new List<ArtistImage>();
            this.Videos = new List<YoutubeVideo>();
            this.Tags = new ArtistTags();
        }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("image")]
        public List<ArtistImage> Images { get; set; }

        [JsonProperty("url")]
        public string Url { get; set; }

        [JsonProperty("tags")]
        public ArtistTags Tags { get; set; }

        [JsonProperty("bio")]
        public ArtistBio Bio { get; set; }

        public List<YoutubeVideo> Videos { get; set; }
    }

    public class ArtistTags
    {
        public ArtistTags()
        {
            this.Tags = new List<ArtistTag>();
        }

        [JsonProperty("tag")]
        public List<ArtistTag> Tags { get; set; }
    }

    public class ArtistTag
    {
        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("url")]
        public string Url { get; set; }
    }

    public class ArtistBio
    {
        [JsonProperty("summary")]
        public string Summary { get; set; }

        [JsonProperty("content")]
        public string Content { get; set; }
    }
}